Window Focus Refetching
如果用户离开应用程序并返回,而查询数据已过时,TanStack Query 会自动在后台为您请求新的数据。您可以使用refetchOnWindowFocus
选项在全局或每个查询中禁用此功能。
全局禁用
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false // default: true
}
}
})
function App() {
return <QueryClientProvider client={queryClient}>...</QueryClientProvider>
}
每个query禁用
useQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
refetchOnWindowFocus: false
})
自定义窗口焦点事件处理程序
在极少数情况下,您可能希望管理自己的窗口焦点事件,以触发TanStack Query的重新验证。为此,TanStack Query提供了focusManager.setEventListener
函数,该函数提供了在窗口获得焦点时应触发的回调函数,并允许您设置自己的事件。在调用focusManager.setEventListener
时,先前设置的处理程序将被删除(在大多数情况下,这将是默认处理程序),而将使用您的新处理程序。例如,以下是默认处理程序:
focusManager.setEventListener((handleFocus) => {
if (typeof window !== 'undefined' && window.addEventListener) {
window.addEventListener('visibilitychange', handleFocus, false)
window.addEventListener('focus', handleFocus, false)
}
return () => {
// Be sure to unsubscribe if a new handler is set
window.removeEventListener('visibilitychange', handleFocus)
window.removeEventListener('focus', handleFocus)
}
})
忽略Iframe焦点事件
替换焦点处理程序的一个很好的用例是iframe事件。iframe在检测窗口焦点时存在问题,因为它们会重复触发事件,并且在应用程序内部聚焦或使用iframe时会触发错误的事件。如果遇到此问题,您应该使用尽可能忽略这些事件的事件处理程序。我推荐使用上述链接中的处理程序!可以按以下方式设置:
import { focusManager } from "@tanstack/react-query"
import onWindowFocus from './onWindowFocus' // 上面的代码片段
focusManager.setEventListener(onWindowFocus) // 搞定
在React Native中管理焦点
与在窗口上添加事件侦听器不同,React Native通过AppState模块提供了焦点信息。您可以使用AppState的"change"事件在应用程序状态更改为"active"时触发更新:
import { AppState } from 'react-native'
import { focusManager } from "@tanstack/react-query"
function onAppStateChange(status: AppStateStatus) {
if (Platform.OS !== 'web') {
focusManager.setFocused(status === 'active')
}
}
useEffect(() => {
const subscription = AppState.addEventListener('change', onAppStateChange)
return () => subscription.remove()
}, [])
管理焦点状态
import { focusManager } from '@tanstack/react-query'
// 覆盖默认的焦点状态
focusManager.setFocused(true)
// 回退到默认的焦点检查
focusManager.setFocused(undefined)
注意事项和注意事项
某些浏览器内部对话框窗口,例如通过alert()
生成的对话框或文件上传对话框(通过<input type="file" />
创建)在关闭后也可能触发焦点重新获取。这可能导致意外的副作用,因为重新获取可能在执行文件上传处理程序之前触发组件的卸载或重新挂载。有关背景和可能的解决方法,请参阅GitHub上的此问题。